<?php
require_once('Evaluator.php');

class Node{
  protected $attributes=array();
  protected $childNodes=array();
  protected $tpl='';
  protected $script='';
  function __construct($node, $xforms_processor){
    $this->node = $node;
    $this->document = $node->ownerDocument;
    $this->xforms_processor = $xforms_processor;
    $this->xforms_processor->append($this);
    //3.2.1 -> anyAttribute
    if($node->hasAttributes()) {
      foreach($node->attributes as $a) {
        $this->attributes[$a->nodeName]=$a->nodeValue;
      }
    }
    if($this->node->hasChildNodes()) {
      foreach($this->node->childNodes as $ch) {
        $this->childNodes[] = $xforms_processor->factory($ch);
      }
    }
  }
  function getXPath($node=null){
    return $this->xforms_processor->getXPath($this->node);
  }
  function render() {
    $res = $this->render2();
    $dom = new DOMDocument();
    //El html de la fuente para cargar los xmlns del formulario
    $html = $dom->importNode($this->document->childNodes->item(0)->cloneNode(false));
    $dom->appendChild($html);
    $res0="";
    foreach($res as $ch){
      $html->appendChild($e=$dom->importNode($ch,true));
      //$res0.=$this->xforms_processor->output->saveXML($ch);
      $res0.=$dom->saveXML($e);
    }
    return $res0;
  }
  function renderChildNodes($whiteList=array(),$blackList=array(),$glue='') {
    $res = array();
    foreach($this->childNodes as $ch) {
      if(
          (!$whiteList || (array_search($ch->node->nodeName, $whiteList)!==false)) &&
          (!$blackList || (array_search($ch->node->nodeName, $blackList)===false))
        ) {
        $res[]= $ch->render();
      }
    }
    return implode($glue, $res);
  }
  function render2() {
    if($this->script) {
      $e = new Evaluator();
      $this->xforms_processor->script.= $e->evaluate($this->script, $this);
    }
    if($this->tpl) {
      //procesa templeta
      $n = $this->node->cloneNode(false);
      $nr = $this->xforms_processor->output->importNode($n);
      $e = new Evaluator();
      $tpl = $e->evaluate($this->tpl, $this);
      $dom = new DOMDocument();
      //Se carga sin xmlns para borrar los ns 
      set_error_handler('HandleXmlError');
      $pre = '<?xml version="1.0" encoding="utf-8"?>'."\n".'<!DOCTYPE root 
[
<!ENTITY nbsp   "&#160;" >
<!ENTITY iexcl  "&#161;" >
<!ENTITY cent   "&#162;" >
<!ENTITY pound  "&#163;" >
<!ENTITY curren "&#164;" >
<!ENTITY yen    "&#165;" >
<!ENTITY brvbar "&#166;" >
<!ENTITY sect   "&#167;" >
<!ENTITY uml    "&#168;" >
<!ENTITY copy   "&#169;" >
<!ENTITY ordf   "&#170;" >
<!ENTITY laquo  "&#171;" >
<!ENTITY not    "&#172;" >
<!ENTITY shy    "&#173;" >
<!ENTITY reg    "&#174;" >
<!ENTITY macr   "&#175;" >
<!ENTITY deg    "&#176;" >
<!ENTITY plusmn "&#177;" >
<!ENTITY sup2   "&#178;" >
<!ENTITY sup3   "&#179;" >
<!ENTITY acute  "&#180;" >
<!ENTITY micro  "&#181;" >
<!ENTITY para   "&#182;" >
<!ENTITY middot "&#183;" >
<!ENTITY cedil  "&#184;" >
<!ENTITY sup1   "&#185;" >
<!ENTITY ordm   "&#186;" >
<!ENTITY raquo  "&#187;" >
<!ENTITY frac14 "&#188;" >
<!ENTITY frac12 "&#189;" >
<!ENTITY frac34 "&#190;" >
<!ENTITY iquest "&#191;" >
<!ENTITY Agrave "&#192;" >
<!ENTITY Aacute "&#193;" >
<!ENTITY Acirc  "&#194;" >
<!ENTITY Atilde "&#195;" >
<!ENTITY Auml   "&#196;" >
<!ENTITY Aring  "&#197;" >
<!ENTITY AElig  "&#198;" >
<!ENTITY Ccedil "&#199;" >
<!ENTITY Egrave "&#200;" >
<!ENTITY Eacute "&#201;" >
<!ENTITY Ecirc  "&#202;" >
<!ENTITY Euml   "&#203;" >
<!ENTITY Igrave "&#204;" >
<!ENTITY Iacute "&#205;" >
<!ENTITY Icirc  "&#206;" >
<!ENTITY Iuml   "&#207;" >
<!ENTITY ETH    "&#208;" >
<!ENTITY Ntilde "&#209;" >
<!ENTITY Ograve "&#210;" >
<!ENTITY Oacute "&#211;" >
<!ENTITY Ocirc  "&#212;" >
<!ENTITY Otilde "&#213;" >
<!ENTITY Ouml   "&#214;" >
<!ENTITY times  "&#215;" >
<!ENTITY Oslash "&#216;" >
<!ENTITY Ugrave "&#217;" >
<!ENTITY Uacute "&#218;" >
<!ENTITY Ucirc  "&#219;" >
<!ENTITY Uuml   "&#220;" >
<!ENTITY Yacute "&#221;" >
<!ENTITY THORN  "&#222;" >
<!ENTITY szlig  "&#223;" >
<!ENTITY agrave "&#224;" >
<!ENTITY aacute "&#225;" >
<!ENTITY acirc  "&#226;" >
<!ENTITY atilde "&#227;" >
<!ENTITY auml   "&#228;" >
<!ENTITY aring  "&#229;" >
<!ENTITY aelig  "&#230;" >
<!ENTITY ccedil "&#231;" >
<!ENTITY egrave "&#232;" >
<!ENTITY eacute "&#233;" >
<!ENTITY ecirc  "&#234;" >
<!ENTITY euml   "&#235;" >
<!ENTITY igrave "&#236;" >
<!ENTITY iacute "&#237;" >
<!ENTITY icirc  "&#238;" >
<!ENTITY iuml   "&#239;" >
<!ENTITY eth    "&#240;" >
<!ENTITY ntilde "&#241;" >
<!ENTITY ograve "&#242;" >
<!ENTITY oacute "&#243;" >
<!ENTITY ocirc  "&#244;" >
<!ENTITY otilde "&#245;" >
<!ENTITY ouml   "&#246;" >
<!ENTITY divide "&#247;" >
<!ENTITY oslash "&#248;" >
<!ENTITY ugrave "&#249;" >
<!ENTITY uacute "&#250;" >
<!ENTITY ucirc  "&#251;" >
<!ENTITY uuml   "&#252;" >
<!ENTITY yacute "&#253;" >
<!ENTITY thorn  "&#254;" >
<!ENTITY yuml   "&#255;" >
<!ENTITY mdash  "&#8212;" >
]
>
<html>';
      $GLOBALS["current_pre"] = $pre;
      $GLOBALS["current_tpl"] = $tpl;
      $GLOBALS["current_object"] = $this;
      $dom->loadXML($pre.$tpl.'</html>', LIBXML_COMPACT  );
      restore_error_handler();
      $res = array();
      foreach($dom->childNodes->item(1)->childNodes as $ch){
        $res[]=$this->xforms_processor->output->importNode($ch, true);
      }
      return $res;
    } else {
      $n = $this->node->cloneNode(false);
      $nr = $this->xforms_processor->output->importNode($n);
      foreach($this->childNodes as $ch) {
        $ni = $ch->render2();
        foreach($ni as $nii){
          $nr->appendChild($nii);
        }
      }
      return array($nr);
    }
  }
  function renderAttributes() {
    $res=array();
    foreach($this->node->attributes as $a){
      $res[]=$a->nodeName.'="'.htmlentities($a->nodeValue, ENT_QUOTES,'utf-8').'"';
    }
    return implode(" ",$res);
  }
  function renderJson() {
    $res=new StdClass();
    foreach($this->node->attributes as $a){
      $name = $a->nodeName;
      $res->$name = $a->nodeValue;
    }
    $res->_xpath=$this->getXPath();
    if($this instanceof XForms_Core) {
      $b = $this->getBinding();
      if($b) {
        if($b->getAttribute("id")) {
          $res->_binding = $b->getAttribute("id");
        } else {
          $res->_binding = $this->xforms_processor->getXPath($b);
        }
      }
    }
    return json_encode($res);
  }
  function renderId(){
    $id = $this->node->getAttribute('id');
    if(!$id){
      $id = $this->getXPath();
    }
    return ' id="'.htmlentities($id, ENT_QUOTES, 'utf-8').'"';
  }
  function getXElement($node){
    return $this->xforms_processor->findXElement($node);
  }
}
function HandleXmlError($errno, $errstr, $errfile, $errline)
{
    if ($errno==E_WARNING && (substr_count($errstr,"Namespace prefix ")>0)) {
      return true;
    }
    else {
      echo '<b>CLASS: '.get_class($GLOBALS["current_object"]).'</b><br />';
      echo $errstr;
      echo '<pre style="background-image:url(images/line-numbers.png);background-position:0px '.(16-16*(count(explode("\n",$GLOBALS["current_pre"]))-1)).'px;background-repeat:no-repeat;padding:26px;line-height: 16px;">'.htmlentities($GLOBALS["current_tpl"], ENT_NOQUOTES, 'utf-8').'</pre>';
      //echo $errstr . '<pre style="background-image:url(images/line-numbers.png);background-position:0px '.(16).'px;background-repeat:no-repeat;padding:26px;line-height: 16px;">'.htmlentities($GLOBALS["current_pre"].$GLOBALS["current_tpl"], ENT_NOQUOTES, 'utf-8').'</pre>';
      return true /*false*/;
    }
}
